package com.njuse.jvmfinal.runtimestructure;

import java.util.HashMap;

import com.njuse.jvmfinal.Instruction.AALOAD;
import com.njuse.jvmfinal.Instruction.AASTORE;
import com.njuse.jvmfinal.Instruction.ACONST_NULL;
import com.njuse.jvmfinal.Instruction.ALOAD;
import com.njuse.jvmfinal.Instruction.ALOAD_N;
import com.njuse.jvmfinal.Instruction.ARETURN;
import com.njuse.jvmfinal.Instruction.ARRAYLENGTH;
import com.njuse.jvmfinal.Instruction.ASTORE;
import com.njuse.jvmfinal.Instruction.ASTORE_N;
import com.njuse.jvmfinal.Instruction.BIPUSH;
import com.njuse.jvmfinal.Instruction.CALOAD;
import com.njuse.jvmfinal.Instruction.CASTORE;
import com.njuse.jvmfinal.Instruction.D2F;
import com.njuse.jvmfinal.Instruction.D2I;
import com.njuse.jvmfinal.Instruction.D2L;
import com.njuse.jvmfinal.Instruction.DADD;
import com.njuse.jvmfinal.Instruction.DCMPG;
import com.njuse.jvmfinal.Instruction.DCMPL;
import com.njuse.jvmfinal.Instruction.DCONST_N;
import com.njuse.jvmfinal.Instruction.DLOAD;
import com.njuse.jvmfinal.Instruction.DLOAD_N;
import com.njuse.jvmfinal.Instruction.DRETURN;
import com.njuse.jvmfinal.Instruction.DSTORE;
import com.njuse.jvmfinal.Instruction.DSTORE_N;
import com.njuse.jvmfinal.Instruction.DUP;
import com.njuse.jvmfinal.Instruction.F2D;
import com.njuse.jvmfinal.Instruction.F2I;
import com.njuse.jvmfinal.Instruction.F2L;
import com.njuse.jvmfinal.Instruction.FADD;
import com.njuse.jvmfinal.Instruction.FCMPG;
import com.njuse.jvmfinal.Instruction.FCMPL;
import com.njuse.jvmfinal.Instruction.FCONST_N;
import com.njuse.jvmfinal.Instruction.FLOAD;
import com.njuse.jvmfinal.Instruction.FLOAD_N;
import com.njuse.jvmfinal.Instruction.FRETURN;
import com.njuse.jvmfinal.Instruction.FSTORE;
import com.njuse.jvmfinal.Instruction.GETFIELD;
import com.njuse.jvmfinal.Instruction.GETSTATIC;
import com.njuse.jvmfinal.Instruction.GOTO;
import com.njuse.jvmfinal.Instruction.I2B;
import com.njuse.jvmfinal.Instruction.I2C;
import com.njuse.jvmfinal.Instruction.I2D;
import com.njuse.jvmfinal.Instruction.I2L;
import com.njuse.jvmfinal.Instruction.I2S;
import com.njuse.jvmfinal.Instruction.IADD;
import com.njuse.jvmfinal.Instruction.IALOAD;
import com.njuse.jvmfinal.Instruction.IASTORE;
import com.njuse.jvmfinal.Instruction.ICONST_N;
import com.njuse.jvmfinal.Instruction.IDIV;
import com.njuse.jvmfinal.Instruction.IFEQ;
import com.njuse.jvmfinal.Instruction.IFGE;
import com.njuse.jvmfinal.Instruction.IFLE;
import com.njuse.jvmfinal.Instruction.IFNE;
import com.njuse.jvmfinal.Instruction.IFNONNULL;
import com.njuse.jvmfinal.Instruction.IFNULL;
import com.njuse.jvmfinal.Instruction.IF_ICMPEQ;
import com.njuse.jvmfinal.Instruction.IF_ICMPGE;
import com.njuse.jvmfinal.Instruction.IF_ICMPGT;
import com.njuse.jvmfinal.Instruction.IF_ICMPLE;
import com.njuse.jvmfinal.Instruction.IF_ICMPLT;
import com.njuse.jvmfinal.Instruction.IF_ICMPNE;
import com.njuse.jvmfinal.Instruction.IINC;
import com.njuse.jvmfinal.Instruction.ILOAD;
import com.njuse.jvmfinal.Instruction.ILOAD_N;
import com.njuse.jvmfinal.Instruction.IMUL;
import com.njuse.jvmfinal.Instruction.INEG;
import com.njuse.jvmfinal.Instruction.INSTANCEOF;
import com.njuse.jvmfinal.Instruction.INVOKE_INTERFACE;
import com.njuse.jvmfinal.Instruction.INVOKE_SPECIAL;
import com.njuse.jvmfinal.Instruction.INVOKE_STATIC;
import com.njuse.jvmfinal.Instruction.INVOKE_VIRTUAL;
import com.njuse.jvmfinal.Instruction.IRETURN;
import com.njuse.jvmfinal.Instruction.ISHL;
import com.njuse.jvmfinal.Instruction.ISTORE;
import com.njuse.jvmfinal.Instruction.ISTORE_N;
import com.njuse.jvmfinal.Instruction.ISUB;
import com.njuse.jvmfinal.Instruction.IXOR;
import com.njuse.jvmfinal.Instruction.Instruction;
import com.njuse.jvmfinal.Instruction.L2D;
import com.njuse.jvmfinal.Instruction.L2F;
import com.njuse.jvmfinal.Instruction.L2I;
import com.njuse.jvmfinal.Instruction.LADD;
import com.njuse.jvmfinal.Instruction.LCMP;
import com.njuse.jvmfinal.Instruction.LCONST_N;
import com.njuse.jvmfinal.Instruction.LDC;
import com.njuse.jvmfinal.Instruction.LDC2_W;
import com.njuse.jvmfinal.Instruction.LLOAD;
import com.njuse.jvmfinal.Instruction.LLOAD_N;
import com.njuse.jvmfinal.Instruction.LRETURN;
import com.njuse.jvmfinal.Instruction.LSTORE;
import com.njuse.jvmfinal.Instruction.MULTIANEWARRAY;
import com.njuse.jvmfinal.Instruction.NEW;
import com.njuse.jvmfinal.Instruction.NEWARRAY;
import com.njuse.jvmfinal.Instruction.POP;
import com.njuse.jvmfinal.Instruction.PUTFIELD;
import com.njuse.jvmfinal.Instruction.PUTSTATIC;
import com.njuse.jvmfinal.Instruction.RETURN;
import com.njuse.jvmfinal.Instruction.SIPUSH;


public class decoder {
	  private static HashMap<Integer, Instruction> opMap;

	    static {
	        opMap = new HashMap<>();
	        opMap.put(OpCode.ACONST_NULL, new ACONST_NULL());
	        opMap.put(OpCode.ICONST_M1, new ICONST_N(-1));
            opMap.put(OpCode.ICONST_0, new ICONST_N(0));
	        opMap.put(OpCode.ICONST_1, new ICONST_N(1));
	        opMap.put(OpCode.ICONST_2, new ICONST_N(2));
	        opMap.put(OpCode.ICONST_3, new ICONST_N(3));
	        opMap.put(OpCode.ICONST_4, new ICONST_N(4));
	        opMap.put(OpCode.ICONST_5, new ICONST_N(5));
	        opMap.put(OpCode.LCONST_0, new LCONST_N(0));
	        opMap.put(OpCode.LCONST_1, new LCONST_N(1));
	        opMap.put(OpCode.BIPUSH, new BIPUSH());
	        opMap.put(OpCode.SIPUSH, new SIPUSH());
	        opMap.put(OpCode.LDC, new LDC());
	        opMap.put(OpCode.LDC2_W, new LDC2_W());
	        opMap.put(OpCode.ILOAD, new ILOAD());
	        opMap.put(OpCode.POP, new POP());
	        opMap.put(OpCode.DUP, new DUP());
	        opMap.put(OpCode.ILOAD_0, new ILOAD_N(0));
	        opMap.put(OpCode.ILOAD_1, new ILOAD_N(1));
	        opMap.put(OpCode.ILOAD_2, new ILOAD_N(2));
	        opMap.put(OpCode.ILOAD_3, new ILOAD_N(3));
	        opMap.put(OpCode.LLOAD_0, new LLOAD_N(0));
	        opMap.put(OpCode.LLOAD_1, new LLOAD_N(1));
	        opMap.put(OpCode.LLOAD_2, new LLOAD_N(2));
	        opMap.put(OpCode.LLOAD_3, new LLOAD_N(3));
	        opMap.put(OpCode.LLOAD, new LLOAD());
	        opMap.put(OpCode.ALOAD_0, new ALOAD_N(0));
	        opMap.put(OpCode.ALOAD_1, new ALOAD_N(1));
	        opMap.put(OpCode.ALOAD_2, new ALOAD_N(2));
	        opMap.put(OpCode.ALOAD_3, new ALOAD_N(3));
	        opMap.put(OpCode.DCONST_0,new DCONST_N(0.0));
	        opMap.put(OpCode.DCONST_1,new DCONST_N(1.0));
	        opMap.put(OpCode.DLOAD,new DLOAD());
	        opMap.put(OpCode.DLOAD_0,new DLOAD_N(0));
	        opMap.put(OpCode.DLOAD_1,new DLOAD_N(1));
	        opMap.put(OpCode.DLOAD_2,new DLOAD_N(2));
	        opMap.put(OpCode.DLOAD_3,new DLOAD_N(3));
	        opMap.put(OpCode.ALOAD,new ALOAD());
	        opMap.put(OpCode.IALOAD, new IALOAD());
	        opMap.put(OpCode.IASTORE, new IASTORE());
	        opMap.put(OpCode.AALOAD, new AALOAD());
	        opMap.put(OpCode.AASTORE, new AASTORE());
	        opMap.put(OpCode.CALOAD, new CALOAD());
	        opMap.put(OpCode.CASTORE, new CASTORE());
	        opMap.put(OpCode.ASTORE, new ASTORE());
	        opMap.put(OpCode.ISTORE, new ISTORE());
	        opMap.put(OpCode.ISTORE_0, new ISTORE_N(0));
	        opMap.put(OpCode.ISTORE_1, new ISTORE_N(1));
	        opMap.put(OpCode.ISTORE_2, new ISTORE_N(2));
	        opMap.put(OpCode.ISTORE_3, new ISTORE_N(3));
	        opMap.put(OpCode.DSTORE,new DSTORE());
	        opMap.put(OpCode.DSTORE_0, new DSTORE_N(0));
	        opMap.put(OpCode.DSTORE_1, new DSTORE_N(1));
	        opMap.put(OpCode.DSTORE_2, new DSTORE_N(2));
	        opMap.put(OpCode.DSTORE_3, new DSTORE_N(3));
	        opMap.put(OpCode.ASTORE_0, new ASTORE_N(0));
	        opMap.put(OpCode.ASTORE_1, new ASTORE_N(1));
	        opMap.put(OpCode.ASTORE_2, new ASTORE_N(2));
	        opMap.put(OpCode.ASTORE_3, new ASTORE_N(3));
            opMap.put(OpCode.ARRAYLENGTH, new ARRAYLENGTH());
	        opMap.put(OpCode.GOTO_, new GOTO());
	        opMap.put(OpCode.IRETURN, new IRETURN());
	        opMap.put(OpCode.LRETURN, new LRETURN());
	        opMap.put(OpCode.FRETURN, new FRETURN());
	        opMap.put(OpCode.DRETURN, new DRETURN());
	        opMap.put(OpCode.ARETURN, new ARETURN());
	        opMap.put(OpCode.RETURN_, new RETURN());
	        opMap.put(OpCode.GETSTATIC, new GETSTATIC());
	        opMap.put(OpCode.PUTSTATIC, new PUTSTATIC());
	        opMap.put(OpCode.GETFIELD, new GETFIELD());
	        opMap.put(OpCode.PUTFIELD, new PUTFIELD());
	        opMap.put(OpCode.INVOKEVIRTUAL, new INVOKE_VIRTUAL());
	        opMap.put(OpCode.INVOKESPECIAL, new INVOKE_SPECIAL());
	        opMap.put(OpCode.INVOKESTATIC,  new INVOKE_STATIC());
	        opMap.put(OpCode.INVOKEINTERFACE, new INVOKE_INTERFACE());
	        opMap.put(OpCode.NEW_, new NEW());
	        opMap.put(OpCode.IFEQ, new IFEQ());
	        opMap.put(OpCode.IFNE, new IFNE());
	        opMap.put(OpCode.IFGE, new IFGE());
	        opMap.put(OpCode.IFLE, new IFLE());
	        opMap.put(OpCode.IF_ICMPNE, new IF_ICMPNE());
	        opMap.put(OpCode.IF_ICMPGE, new IF_ICMPGE());
	        opMap.put(OpCode.IF_ICMPLE, new IF_ICMPLE());
	        opMap.put(OpCode.IF_ICMPLT, new IF_ICMPLT());
	        opMap.put(OpCode.IF_ICMPGT, new IF_ICMPGT());
	        opMap.put(OpCode.IF_ICMPEQ, new IF_ICMPEQ());
	        opMap.put(OpCode.IFNONNULL, new IFNONNULL());
	        opMap.put(OpCode.IFNULL, new IFNULL());
	        opMap.put(OpCode.LCMP,new LCMP());
	        opMap.put(OpCode.FLOAD,new FLOAD());
	        opMap.put(OpCode.FLOAD_0,new FLOAD_N(0));
	        opMap.put(OpCode.FLOAD_1,new FLOAD_N(1));
	        opMap.put(OpCode.FLOAD_2,new FLOAD_N(2));
	        opMap.put(OpCode.FLOAD_3,new FLOAD_N(3));
	        opMap.put(OpCode.FSTORE,new FSTORE());
	        opMap.put(OpCode.FCMPG,new FCMPG());
	        opMap.put(OpCode.FCMPL,new FCMPL());
	        opMap.put(OpCode.DCMPG,new DCMPG());
	        opMap.put(OpCode.DCMPL,new DCMPL());
	        opMap.put(OpCode.IINC,new IINC());
	        opMap.put(OpCode.IADD,new IADD());
	        opMap.put(OpCode.D2F,new D2F());
	        opMap.put(OpCode.D2I,new D2I());
	        opMap.put(OpCode.D2L,new D2L());
	        opMap.put(OpCode.DADD,new DADD());
	        opMap.put(OpCode.F2D,new F2D());
	        opMap.put(OpCode.F2I,new F2I());
	        opMap.put(OpCode.F2L,new F2L());
	        opMap.put(OpCode.FADD,new FADD());
	        opMap.put(OpCode.I2B,new I2B());
	        opMap.put(OpCode.I2C,new I2C());
	        opMap.put(OpCode.I2D,new I2D());
	        opMap.put(OpCode.I2L,new I2L());
	        opMap.put(OpCode.I2S,new I2S());
	        opMap.put(OpCode.INEG,new INEG());
	        opMap.put(OpCode.ISHL,new ISHL());
	        opMap.put(OpCode.L2D,new L2D());
	        opMap.put(OpCode.L2F,new L2F());
	        opMap.put(OpCode.L2I,new L2I());
	        opMap.put(OpCode.LADD,new LADD());
	        opMap.put(OpCode.LSTORE,new LSTORE());
	        opMap.put(OpCode.FCONST_0,new FCONST_N(0));
	        opMap.put(OpCode.FCONST_1,new FCONST_N(1));
	        opMap.put(OpCode.FCONST_2,new FCONST_N(2));
	        opMap.put(OpCode.IMUL,new IMUL());
	        opMap.put(OpCode.IDIV,new IDIV());
	        opMap.put(OpCode.ISUB,new ISUB());
	        opMap.put(OpCode.IXOR,new IXOR());
	        opMap.put(OpCode.NEWARRAY,new NEWARRAY());
	        opMap.put(OpCode.MULTIANEWARRAY,new MULTIANEWARRAY());
	        opMap.put(OpCode.INSTANCEOF_, new INSTANCEOF());
	    }
	public static Instruction decode(int number) {
		if (opMap.get(number)==null) throw new RuntimeException(number+"notfound");
		    return opMap.get(number);
		}
	}
